package com.googlecode.publicholiday.web;

import com.googlecode.publicholiday.service.PublicHolidayService;
import org.joda.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.Iterator;

import static org.springframework.format.annotation.DateTimeFormat.ISO.DATE;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.web.bind.annotation.RequestMethod.*;

@Controller
@RequestMapping(value = "/publicHoliday/{countryCode}")
public class SpringPublicHolidayController {

    private final PublicHolidayService publicHolidayService;

    public SpringPublicHolidayController(PublicHolidayService publicHolidayService) {
        this.publicHolidayService = publicHolidayService;
    }

    @RequestMapping(value = "/from/{startDate}/to/{endDate}", method = GET)
    @ResponseStatus( HttpStatus.OK )
    @ResponseBody
    public String get(@PathVariable String countryCode, @PathVariable @DateTimeFormat(iso = DATE) LocalDate startDate, @PathVariable @DateTimeFormat(iso = DATE) LocalDate endDate) {
        Iterator<LocalDate> holidays = publicHolidayService.find(countryCode, startDate, endDate).iterator();
        if (!holidays.hasNext()) {
            throw new ResourceNotFoundException("Could not find PublicHolidays between " + startDate + " and " + endDate);
        } else {
            StringBuilder sb = new StringBuilder("<publicHolidays countryCode=\"").append(countryCode).append("\">\n");
            while (holidays.hasNext()) {
                sb.append("<publicHoliday date=\"").append(holidays.next().toString()).append("\"/>\n");
            }
            sb.append("</publicHolidays>");
            return sb.toString();
        }
    }

    @RequestMapping(value = "/{publicHoliday}", method = POST)
    @ResponseStatus( HttpStatus.CREATED )
    public void create(@PathVariable String countryCode, @PathVariable @DateTimeFormat(iso = DATE) LocalDate publicHoliday) {
        publicHolidayService.create(countryCode, publicHoliday);
    }

    @RequestMapping(value = "/{publicHoliday}", method = DELETE)
    @ResponseStatus( HttpStatus.OK )
    public void delete(@PathVariable String countryCode, @PathVariable @DateTimeFormat(iso = DATE) LocalDate publicHoliday) {
        publicHolidayService.delete(countryCode, publicHoliday);
    }

    /**
     *
     * @param countryCode
     * @param dateInQuestion
     * @return
     */
    @RequestMapping(value = "/{dateInQuestion}", method = GET)
    @ResponseStatus( HttpStatus.OK )
    public void isPublicHoliday(@PathVariable String countryCode, @PathVariable @DateTimeFormat(iso = DATE) LocalDate dateInQuestion) {
        if (!publicHolidayService.isPublicHoliday(countryCode, dateInQuestion)) {
            throw new ResourceNotFoundException("Could not find a PublicHoliday on " + dateInQuestion);
        }
    }

    @ResponseStatus(value = NOT_FOUND)
    public final class ResourceNotFoundException extends RuntimeException {

        public ResourceNotFoundException() {
            super();
        }

        public ResourceNotFoundException(String message) {
            super(message);
        }
    }
}
